package com.tanhua.dubbo.api;

import com.tanhua.domain.mongo.Comment;
import com.tanhua.domain.mongo.Publish;
import com.tanhua.domain.vo.PageResult;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import java.util.List;

/**
 * @author liuyp
 * @date 2021/02/01
 */
@Service
public class CommentApiImpl implements CommentApi {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public long save(Comment comment) {
        //1. 补全数据
        comment.setId(ObjectId.get());
        comment.setCreated(System.currentTimeMillis());

        //2. 存储到MongoDB
        mongoTemplate.save(comment);

        //3. 更新动态的计数：+1。
        // 如果操作类型commentType是1：是点赞，要对publish的likeCount+1
        // 如果操作类型commentType是2：是文字评论，要对publish的commentCount+1
        // 如果操作类型commentType是3：是喜欢，要对publish的loveCount+1
        Query query = new Query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update().inc(getColumnName(comment.getCommentType()), 1);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);

        Publish publish = mongoTemplate.findAndModify(query, update, options, Publish.class);

        return getCount(publish, comment.getCommentType());
    }

    @Override
    public long remove(Comment comment) {
        //1. 删除之前的评论数据{userId: 124, publishId: xxxx, commentType: 1}
        Criteria criteria = Criteria.where("userId").is(comment.getUserId())
                .and("publishId").is(comment.getPublishId())
                .and("commentType").is(comment.getCommentType());

        mongoTemplate.remove(new Query(criteria), Comment.class);

        //2. 更新计数：-1
        Query query = new Query(Criteria.where("id").is(comment.getPublishId()));
        Update update = new Update().inc(getColumnName(comment.getCommentType()), -1);
        FindAndModifyOptions options = new FindAndModifyOptions();
        options.returnNew(true);

        Publish publish = mongoTemplate.findAndModify(query, update, options, Publish.class);

        //3. 获取并返回最新计数
        return getCount(publish, comment.getCommentType());
    }

    @Override
    public PageResult<Comment> findCommentList(int page, int pagesize, String publishId) {
        Criteria criteria = Criteria.where("publishId").is(new ObjectId(publishId))
                .and("commentType").is(2);
        Query query = new Query(criteria)
                .with(Sort.by(Sort.Order.desc("likeCount"), Sort.Order.desc("created")))
                .with(PageRequest.of(page-1, pagesize));

        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        long count = mongoTemplate.count(query, Comment.class);

        int pages = (int) Math.ceil(count * 1.0 / pagesize);
        return new PageResult<>((int)count, pagesize, pages, page, commentList);
    }

    @Override
    public PageResult<Comment> findCommentListByType(int page, int pagesize, long userId, int commentType) {
        Criteria criteria = Criteria.where("publishUserId").is(userId).and("commentType").is(commentType);
        Query query = new Query(criteria)
                .with(Sort.by(Sort.Order.desc("created")))
                .with(PageRequest.of(page-1, pagesize));

        List<Comment> commentList = mongoTemplate.find(query, Comment.class);
        long count = mongoTemplate.count(query, Comment.class);
        int pages = (int) Math.ceil(count * 1.0 / pagesize);

        return new PageResult<>((int)count, pagesize, pages, page, commentList);
    }

    private String getColumnName(Integer commentType){
        if (commentType == 1) {
            //点赞了，要更新的是likeCount
            return "likeCount";
        }else if(commentType == 2){
            //文字评论，要更新的是commentCount
            return "commentCount";
        }else if(commentType == 3){
            //喜欢了，要更新的是loveCount
            return "loveCount";
        }
        return "";
    }

    public long getCount(Publish publish, Integer commentType){
        if (commentType == 1) {
            //点赞了，要获取最新的点赞数
            return publish.getLikeCount();
        }else if(commentType == 2){
            //文字评论了，要获取最新的文字评论数
            return publish.getCommentCount();
        }else if(commentType == 3){
            //喜欢了，要获取最新的喜欢数
            return publish.getLoveCount();
        }
        return 0;
    }
}
